Data Binding学习笔记——Data Objects
条评论关于 Data Binding 的基本使用在上一篇文章中已经做了总结,接下来会着重介绍下 Data Binding 库中个人认为最重要的两个特性:Data Objects与Attribute Setters。前者是真正能让我们实现数据-UI
双向绑定的关键;后者则为我们提供了自定义 UI 控件数据绑定的可能性。
当然,至于 Data Binding 其他的特性诸如自定义Binding Class命名
、Views with IDs
(此特性可以完全取代Butterknife
啦)等,查阅官方文档可以了。
Data Objects(数据对象)
之前介绍的基本使用中,我们定义的 model 类对象虽然能够绑定对应的 UI 并显示数据,但是修改了对象的属性并不会更新 UI。为此,Data Binding 提供了三种不同的数据变动通知机制: observable objects
、observable fields
和 observable collection
。
当以上的 observable 对象绑定在 UI 上,数据发生变化时,UI 就会同步更新。
1. observable objects
此种方法其实就是让我们定义的 model 类继承一个基类 BaseObservable
,这个类是 Observable
(Data Binding 中的)接口的实现类,内部也就是基于观察者模式的一套添加/移除 listener 的机制。BaseObservable
帮我们实现了 listener 的注册,但是我们需要在 getter
使用 Bindable
注解,并在 setter
中调用方法去发通知。例子:
1 | private static class User extends BaseObservable { |
Bindable
注解会在编译时在 BR 类内生成一个元素(比如上面代码中的 BR.firstName
)。
个人总结:如果一个 model 类的属性有很多,或者是想在原有项目中引入 Data Binding
的话,使用此方法的编写和改动的工作量还是有点繁琐。(不知道有没有开发者已经提供了一键生成的 AS 插件 😏)
2. observable fields
我们还可以使用 ObservableField
及它的派生比如 ObservableInt
、 ObservableBoolean
等作为 model 的数据类型。我们只要在数据类中创建一个 public final 域即可:
1 | private static class User { |
然后要存取数据的话,只需要使用 ObservableField
中的 get
、 set
方法:
1 | user.firstName.set("Google"); |
个人总结:相比第一种方法,代码编写更方便省时,缺点就是:1、数据类的 field
如果很多的话,写起来还是麻烦;2、一般我们都会用到 FastJson
配合 Retrofit
来做 API 请求,结果直接返回给我们对应直接转化好的 model 类对象,所以不太可能直接运用在原本项目中的 model 类中。参考 google 的 todo-mvvm-databinding
中可以发现,原本的 model 类还是不动,每个页面都有一个 ViewModel
类,用于存放该页面中所有的数据对象,都是 ObservableField
相关的类型。
3. observable collections
顾名思义,就是 observable 容器类,个人认为也算是上面一种。
比如使用 ObservableArrayMap
:
1 | ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); |
在 xml 中,可以用 String 类型的 key 来获取 map 中的数据:
1 | <data> |
当 key 是 int 类型还可以使用 ObservableArrayList
,使用的话和 ArrayList
没啥却别:
1 | ObservableArrayList<Object> user = new ObservableArrayList<>(); |
xml 中就是通过下标来获取数据,就不贴代码了 😁。
先写到这,下篇再总结Attribute Setters。